package run.siyuan.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.db.PageResult;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import run.siyuan.entity.Item;
import run.siyuan.repository.EsItemRepository;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author sjj
 * date 2022年09月18日
 */
@Slf4j
@Service
public class EsLazadaItemService {

    @Autowired
    private EsItemRepository esItemRepository;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private ItemService itemService;

    ExecutorService executor = new ThreadPoolExecutor(20, 100, 0L, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<Runnable>(3), Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());


    /**
     * 分页查询
     *
     * @param esLazadaItemQo
     * @return
     */
    public PageResult<Item> pageQueryLazadaItemQo(Item esLazadaItemQo) {
        NativeSearchQuery searchQuery = buildBoolQueryPage(esLazadaItemQo);
        log.info("\nquery:\n{}", searchQuery.getQuery().toString());
        SearchHits<Item> searchHits = elasticsearchRestTemplate.search(searchQuery, Item.class);
        if (searchHits.getTotalHits() == 0) {
            return null;
        }
        List<Item> lazadaItems = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
//        PageResult<Item> pageResult = new PageResult<>(searchHits.getTotalHits(), lazadaItems);
        PageResult<Item> pageResult = new PageResult<>();
        return pageResult;
    }

    /**
     * 查询条件封装-分页
     *
     * @param esLazadaItemQo
     * @return
     */
    private NativeSearchQuery buildBoolQueryPage(Item esLazadaItemQo) {
        //分页起始处理
//        PageUtil.setPage(esLazadaItemQo);
//        Pageable pageable = PageRequest.of(esLazadaItemQo.getPageNo(), esLazadaItemQo.getPageSize());

        NativeSearchQueryBuilder nativeSearchQueryBuilder = buildBoolQuery(esLazadaItemQo);

//        nativeSearchQueryBuilder.withPageable(pageable);

        return nativeSearchQueryBuilder.build();
    }

    /**
     * 查询条件封装-列表
     *
     * @param esLazadaItemQo
     * @return
     */
    private NativeSearchQueryBuilder buildBoolQuery(Item esLazadaItemQo) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // lazadaItemId
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getId())) {
            boolQuery.must(QueryBuilders.termsQuery("id", ListUtil.of(esLazadaItemQo.getId())));
        }
        // 商品id
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getProductId())) {
            boolQuery.must(QueryBuilders.termsQuery("productId", ListUtil.of(esLazadaItemQo.getProductId())));
        }
        // 商品名称
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getProductName())) {
            boolQuery.must(QueryBuilders.matchQuery("productName", esLazadaItemQo.getProductName()));
        }
        // 卖家名称
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getSellerName())) {
            boolQuery.must(QueryBuilders.matchQuery("sellerName", esLazadaItemQo.getSellerName()));
        }
        // youpikCategoryId
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getYoupikCategoryId())) {
            boolQuery.must(QueryBuilders.termQuery("youpikCategoryId", esLazadaItemQo.getYoupikCategoryId()));
        }
        // categoryId
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getCategoryId())) {
            boolQuery.must(QueryBuilders.termQuery("categoryId", esLazadaItemQo.getCategoryId()));
        }
        // categoryTopId
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getCategoryTopId())) {
            boolQuery.must(QueryBuilders.termQuery("categoryTopId", esLazadaItemQo.getCategoryTopId()));
        }
        // 是否精选：0否 1是
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getBestState())) {
            boolQuery.must(QueryBuilders.termQuery("bestState", esLazadaItemQo.getBestState()));
        }
        // 是否品牌：0否 1是
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getBrandState())) {
            boolQuery.must(QueryBuilders.termQuery("brandState", esLazadaItemQo.getBrandState()));
        }
        // 商品状态：0下架 1上架
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getProductState())) {
            boolQuery.must(QueryBuilders.termQuery("productState", esLazadaItemQo.getProductState()));
        }
        // 是否包邮（0否1是）
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getFreeShipping())) {
            boolQuery.must(QueryBuilders.termQuery("freeShipping", esLazadaItemQo.getFreeShipping()));
        }
        // 商品来源（0普通，2-9baht）
        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getSource())) {
            boolQuery.must(QueryBuilders.termQuery("source", esLazadaItemQo.getSource()));
        }
//        // 价格区间
//        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getCurrentPrice$lte()) && ObjectUtils.isNotEmpty(esLazadaItemQo.getCurrentPrice$gte())) {
//            boolQuery.filter(QueryBuilders.rangeQuery("currentPrice").lte(esLazadaItemQo.getCurrentPrice$lte()).gte(esLazadaItemQo.getCurrentPrice$gte()));
//        }
//        // 预估佣金区间
//        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getCommissionFee$lte()) && ObjectUtils.isNotEmpty(esLazadaItemQo.getCommissionFee$gte())) {
//            boolQuery.filter(QueryBuilders.rangeQuery("commissionFee").lte(esLazadaItemQo.getCommissionFee$lte()).gte(esLazadaItemQo.getCommissionFee$gte()));
//        }
//        // 区间
//        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getProductCommissionRate$lte()) && ObjectUtils.isNotEmpty(esLazadaItemQo.getProductCommissionRate$gte())) {
//            boolQuery.filter(QueryBuilders.rangeQuery("productCommissionRate").lte(esLazadaItemQo.getProductCommissionRate$lte()).gte(esLazadaItemQo.getProductCommissionRate$gte()));
//        }
//        // 字段大于number
//        if (CollUtil.isNotEmpty(esLazadaItemQo.getField$gtMap())) {
//            Map<String, Number> field$gtMap = esLazadaItemQo.getField$gtMap();
//            for (String field : esLazadaItemQo.getField$gtMap().keySet()) {
//                boolQuery.filter(QueryBuilders.rangeQuery(field).gt(field$gtMap.get(field)));
//            }
//        }
//        // 闪购场次
//        if (ObjectUtils.isNotEmpty(esLazadaItemQo.getSessionTime())) {
//            BoolQueryBuilder nestedQuery = new BoolQueryBuilder();
//            nestedQuery.must(QueryBuilders.termQuery("lazadaFlashSaleItems.sessionTime", esLazadaItemQo.getSessionTime()));
//            NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("lazadaFlashSaleItems", nestedQuery, ScoreMode.None);
//            boolQuery.must(nestedQueryBuilder);
//        }
//
//        nativeSearchQueryBuilder.withQuery(boolQuery);
//        // 排序字段
//        if (CollUtil.isNotEmpty(esLazadaItemQo.getSortFieldMap())) {
//            Map<String, String> sortFieldMap = esLazadaItemQo.getSortFieldMap();
//            for (Map.Entry<String, String> entry : sortFieldMap.entrySet()) {
//                String field = entry.getKey();
//                String order = entry.getValue();
//                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(field).order(this.getSortOrder(order)));
//            }
//        }

        return nativeSearchQueryBuilder;
    }

    /**
     * 排序转换
     *
     * @param order
     * @return
     */
    private SortOrder getSortOrder(String order) throws Exception {
        if (SortOrder.DESC.toString().equals(order)) {
            return SortOrder.DESC;
        } else if (SortOrder.ASC.toString().equals(order)) {
            return SortOrder.ASC;
        } else {
            throw new Exception("Abnormal sorting");
        }
    }


    public void initLazadaItem(Long lazadaItemId) {
        Long lastLazadaItemId = 0L;
        if (ObjectUtils.isNotEmpty(lazadaItemId)) {
            lastLazadaItemId = lazadaItemId;
        }
        while (true){
            List<Item> lazadaItems = itemService.list(Wrappers.lambdaQuery(Item.class)
                    .gt(Item::getId, lastLazadaItemId)
                    .orderByAsc(Item::getId)
//                    .eq(BaseEntity::getId,lastLazadaItemId)
                    .last("limit 0,200"));
            lazadaItems.forEach(lazadaItem -> {
                executor.execute(() -> {
                itemService.saveOrUpdate(lazadaItem);
                });
            });
            lastLazadaItemId = Long.valueOf(lazadaItems.get(lazadaItems.size() - 1).getId());
            log.info("LazadaItem 商品，lastLazadaItemId: {}" ,lastLazadaItemId);
            // TODO: 2022/10/20
            if (lazadaItems.size() < 200) {
                break;
            }
        }



    }
}
